﻿using Cysharp.Threading.Tasks;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace FastDev
{
    public class ResManager : MonoSingleton<ResManager>, IResManager
    {
        public ResLoadType resLoadType;
        public ResLoader ResLoader { get; } = new ResLoader();
        public ResUpdater ResUpdater { get; } = new ResUpdater();

        private string resPath;
        private ResConfig resLoaderConfig;
        private Dictionary<string, AssetBundle> bundles = new Dictionary<string, AssetBundle>();
        protected override void Awake()
        {
            base.Awake();
            resPath = Application.streamingAssetsPath + "/" + PlatformUtil.GetPlatformName();
            string configPath = resPath + "/" + ResConfig.fileName;
            if (File.Exists(configPath))
            {
                string config = File.ReadAllText(configPath);
                resLoaderConfig = JsonConvert.DeserializeObject<ResConfig>(config);
            }
        }

        [ContextMenu("Load All Bundles")]
        public async UniTask LoadAllAssetBundle()
        {
            if (resLoaderConfig == null)
                return;

            foreach (var item in resLoaderConfig.resDict)
            {
                string path = resPath + "/" + item.Key;

                AssetBundle assetBundle = await ResLoader.LoadAssetBundleAsync(path);

                bundles[item.Key] = assetBundle;
            }
        }

        public void UnloadAssetBundle(string bundleName, bool unloadAll)
        {
            if (bundles.ContainsKey(bundleName))
            {
                ResLoader.UnloadAssetBundle(bundles[bundleName], unloadAll);
            }
        }

        /// <summary>
        /// 加载资源
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="bundleName"></param>
        /// <param name="assetPath"></param>
        /// <returns></returns>
        public T LoadAsset<T>(string bundleName, string assetPath) where T : UnityEngine.Object
        {
#if UNITY_EDITOR
            if (resLoadType == ResLoadType.FromEditor)
            {
                T asset = UnityEditor.AssetDatabase.LoadAssetAtPath<T>(assetPath);
                return asset;
            }
#endif
            if (bundles.ContainsKey(bundleName))
            {
                var assetBundle = bundles[bundleName];
                var assetName = Path.GetFileName(assetPath);
                if (assetBundle.Contains(assetName))
                {
                    return assetBundle.LoadAsset<T>(assetName);
                }
            }
            Debug.LogError("Res Load Failed! " + assetPath);
            return null;
        }

        [ContextMenu("Unload All")]
        public override void Dispose()
        {
            base.Dispose();
            foreach (var item in bundles)
            {
                UnloadAssetBundle(item.Key, true);
            }
            bundles.Clear();
        }
    }
}